<template>
  <div class="verify-code-container">
    <canvas 
      ref="canvasRef" 
      :width="width" 
      :height="height"
      @click="refreshCode"
      class="verify-canvas"
    ></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'

const props = defineProps({
  width: {
    type: Number,
    default: 120
  },
  height: {
    type: Number,
    default: 40
  },
  length: {
    type: Number,
    default: 4
  },
  autoRefresh: {
    type: Boolean,
    default: true
  },
  refreshInterval: {
    type: Number,
    default: 60000 // 60秒
  }
})

const emit = defineEmits(['codeChange'])

const canvasRef = ref(null)
const currentCode = ref('')
let refreshTimer = null

// 生成随机字符
const generateRandomChar = () => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  return chars.charAt(Math.floor(Math.random() * chars.length))
}

// 生成随机颜色
const generateRandomColor = () => {
  const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F']
  return colors[Math.floor(Math.random() * colors.length)]
}

// 生成随机角度
const generateRandomAngle = () => {
  return (Math.random() - 0.5) * 0.4 // -0.2 到 0.2 弧度
}

// 生成随机字体大小
const generateRandomFontSize = () => {
  return Math.floor(Math.random() * 8) + 16 // 16-24px
}

// 绘制验证码
const drawCode = () => {
  const canvas = canvasRef.value
  if (!canvas) return

  const ctx = canvas.getContext('2d')
  const { width, height } = props

  // 清空画布
  ctx.clearRect(0, 0, width, height)

  // 设置背景
  ctx.fillStyle = '#f8f9fa'
  ctx.fillRect(0, 0, width, height)

  // 生成验证码
  let code = ''
  for (let i = 0; i < props.length; i++) {
    code += generateRandomChar()
  }
  currentCode.value = code

  // 绘制字符
  const charWidth = width / props.length
  for (let i = 0; i < code.length; i++) {
    const char = code[i]
    const x = charWidth * i + charWidth / 2
    const y = height / 2 + 5

    ctx.save()
    ctx.translate(x, y)
    ctx.rotate(generateRandomAngle())
    
    ctx.font = `${generateRandomFontSize()}px Arial`
    ctx.fillStyle = generateRandomColor()
    ctx.textAlign = 'center'
    ctx.textBaseline = 'middle'
    ctx.fillText(char, 0, 0)
    
    ctx.restore()
  }

  // 添加干扰线
  for (let i = 0; i < 3; i++) {
    ctx.strokeStyle = generateRandomColor()
    ctx.lineWidth = 1
    ctx.beginPath()
    ctx.moveTo(Math.random() * width, Math.random() * height)
    ctx.lineTo(Math.random() * width, Math.random() * height)
    ctx.stroke()
  }

  // 添加干扰点
  for (let i = 0; i < 20; i++) {
    ctx.fillStyle = generateRandomColor()
    ctx.fillRect(Math.random() * width, Math.random() * height, 1, 1)
  }

  // 触发事件
  emit('codeChange', currentCode.value)
}

// 刷新验证码
const refreshCode = () => {
  drawCode()
}

// 获取当前验证码
const getCurrentCode = () => {
  return currentCode.value
}

// 监听登录失败事件
const handleLoginFailed = () => {
  refreshCode()
}

// 暴露方法给父组件
defineExpose({
  refreshCode,
  getCurrentCode,
  handleLoginFailed
})

// 自动刷新定时器
const startAutoRefresh = () => {
  if (props.autoRefresh && props.refreshInterval > 0) {
    refreshTimer = setInterval(() => {
      refreshCode()
    }, props.refreshInterval)
  }
}

const stopAutoRefresh = () => {
  if (refreshTimer) {
    clearInterval(refreshTimer)
    refreshTimer = null
  }
}

// 监听props变化
watch(() => props.autoRefresh, (newVal) => {
  if (newVal) {
    startAutoRefresh()
  } else {
    stopAutoRefresh()
  }
})

watch(() => props.refreshInterval, () => {
  stopAutoRefresh()
  startAutoRefresh()
})

onMounted(() => {
  drawCode()
  startAutoRefresh()
})

// 组件卸载时清理定时器
import { onUnmounted } from 'vue'
onUnmounted(() => {
  stopAutoRefresh()
})
</script>

<style scoped>
.verify-code-container {
  display: inline-block;
}

.verify-canvas {
  border: 1px solid #ecedec;
  border-radius: 10px;
  cursor: pointer;
  transition: 0.2s ease-in-out;
}

.verify-canvas:hover {
  border-color: #2d79f3;
}
</style> 